home *** CD-ROM | disk | FTP | other *** search
/ World of Education / World of Education.iso / world_x / xcoral16.zip / GET_STRI.C < prev    next >
C/C++ Source or Header  |  1993-01-15  |  13KB  |  463 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/cursorfont.h>
  18. #include <X11/Xutil.h>
  19. #include <X11/keysym.h>
  20. #include <ctype.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <string.h>
  24. #include <pwd.h>
  25.  
  26. #include "options.h"
  27. #include "flist.h"
  28.  
  29. #define D_WIDTH        10
  30. #define D_HEIGHT    10
  31. #define D_SHADOW    6
  32. #define D_WARNING    0
  33. #define D_DIALOG    1
  34. #define D_MESSAGE    2
  35. #define DS_OK        "  Ok...  "
  36. #define DS_DIALOG    "Dialog Box"
  37. #define DS_CANCEL    "Cancel"
  38.  
  39. typedef struct {
  40.     Window        frame, shadow, title, main, ok, cancel;
  41.     unsigned long     fg, bg, ts, bs;
  42.     GC        gc;
  43.     XFontStruct     *font;
  44.     int        t_height, b_width;
  45. } Dialog;
  46.  
  47. Dialog dial;
  48.  
  49. extern Display    *dpy;
  50. extern char     *getenv ();
  51. char         *GetStringFromWindow ();
  52. char        *ExpandTildeName ();
  53.  
  54.  
  55. /*
  56. **    Function name : InitDialogWindow
  57. **
  58. **    Description : Initialisation de la fenetre de dialog,
  59. **        la fonte, les couleurs etc...
  60. **    Input : 
  61. **    Ouput :
  62. */
  63. void InitDialogWindow ()
  64. {
  65.     XSetWindowAttributes att_f;
  66.         Window root;
  67.         int screen;
  68.     unsigned long black, white;
  69.     XGCValues     gcv;
  70.  
  71.     black = BlackPixel ( dpy, DefaultScreen ( dpy ));
  72.     white = WhitePixel ( dpy, DefaultScreen ( dpy ));
  73.  
  74.     dial.fg = (DefaultDepth ( dpy, DefaultScreen ( dpy )) == 1) ? 
  75.         black : GetOpColor ( OP_MENU_FG );
  76.     dial.bg = (DefaultDepth ( dpy, DefaultScreen ( dpy )) == 1) ?
  77.         white : GetOpColor ( OP_MENU_BG );
  78.     dial.ts = GetOpColor ( OP_MENU_TS );
  79.     dial.bs = GetOpColor ( OP_MENU_BS );
  80.     dial.font = GetOpFont ( OP_TEXT_FONT );
  81.  
  82.     dial.gc = XCreateGC ( dpy, DefaultRootWindow ( dpy ), 0,  &gcv );
  83.      XCopyGC ( dpy, DefaultGC (dpy, DefaultScreen ( dpy )), (~0), dial.gc );
  84.  
  85.     XSetFont ( dpy, dial.gc, dial.font -> fid );
  86.     XSetForeground ( dpy, dial.gc, dial.fg );
  87.     XSetBackground ( dpy, dial.gc, dial.bg );
  88.  
  89.     att_f.win_gravity = NorthWestGravity;
  90.     att_f.event_mask = 0;
  91.     att_f.override_redirect = False;
  92.     att_f.do_not_propagate_mask = NoEventMask;
  93.     att_f.cursor = None;
  94.     att_f.win_gravity = NorthWestGravity;
  95.     
  96.         screen = DefaultScreen ( dpy );
  97.     root = RootWindow ( dpy, screen );
  98.  
  99.     dial.frame = XCreateWindow ( dpy, root, 0, 0, D_WIDTH, D_HEIGHT, 0, 0,
  100.         InputOutput, CopyFromParent,
  101.         CWWinGravity | CWEventMask | CWOverrideRedirect |
  102.         CWDontPropagate | CWCursor, &att_f );
  103.         
  104.     dial.shadow = XCreateSimpleWindow ( dpy, dial.frame, D_SHADOW, D_SHADOW, 
  105.         D_WIDTH, D_HEIGHT, 0, black, black);
  106.  
  107.     dial.t_height = dial.font -> ascent + dial.font -> descent + 10;
  108.     dial.title = XCreateSimpleWindow ( dpy,    dial.frame, 0, 0,
  109.         D_WIDTH, dial.t_height, 0, dial.fg, dial.bg);
  110.  
  111.     dial.main = XCreateSimpleWindow ( dpy, dial.frame, 0, dial.t_height,
  112.         D_WIDTH, D_HEIGHT, 0, dial.fg, dial.bg);
  113.  
  114.     dial.b_width = XTextWidth ( dial.font, DS_OK,  strlen (DS_OK)) + 10;
  115.     dial.ok = XCreateSimpleWindow ( dpy, dial.main, 0, 0,
  116.         dial.b_width, dial.t_height, 0, dial.fg, dial.bg );
  117.     
  118.     dial.cancel = XCreateSimpleWindow ( dpy, dial.main, 0, 0,
  119.         dial.b_width, dial.t_height, 0, dial.fg, dial.bg );
  120.  
  121.     XSelectInput ( dpy, dial.main, ExposureMask | KeyPressMask );
  122.     XSelectInput ( dpy, dial.title, ExposureMask );
  123.     XSelectInput ( dpy, dial.cancel, ButtonPressMask |
  124.          ButtonReleaseMask | ExposureMask);
  125.     XSelectInput ( dpy, dial.ok, ButtonPressMask |
  126.          ButtonReleaseMask | ExposureMask );
  127. }
  128.  
  129.  
  130. /*
  131. **    Function name : GetStringFromDialogBox
  132. **
  133. **    Description : Ouvre une fenetre de dialog (grabbee),
  134. **        et manage les differentes actions possibles
  135. **        pour l'utilisaterur. Clavier et bouttons.
  136. **
  137. **    Input : La fenetre parent, le prompt.
  138. **    Ouput : La chaine.
  139. */
  140. char *GetStringFromDialogBox ( w, s )
  141.     Window    w;
  142.     char     *s;
  143. {
  144.     XWindowAttributes att;
  145.     register int width, height, x, y;
  146.     XEvent event;
  147.     register char *str;
  148.     register int type;
  149.  
  150.       XGetWindowAttributes ( dpy, w, &att );
  151.     width = (att.width / 4) * 3;
  152.     height =  (att.height / 3);
  153.     x = att.width / 8;
  154.     y = att.height / 3;
  155.  
  156.     if ( strncmp ( s, "Warning", 7 ) == 0 )
  157.         type = D_WARNING;
  158.     else if ( strncmp ( s, "Message", 7 ) == 0 )
  159.         type = D_MESSAGE;
  160.     else
  161.         type = D_DIALOG;
  162.  
  163.     XReparentWindow ( dpy, dial.frame, w, x, y );
  164.  
  165.     XResizeWindow ( dpy, dial.frame, width, height );
  166.     XResizeWindow ( dpy, dial.shadow, width - D_SHADOW , height - D_SHADOW );
  167.     XResizeWindow ( dpy, dial.main, width - D_SHADOW,
  168.         height - dial.t_height - D_SHADOW );
  169.     XResizeWindow ( dpy, dial.title,  width -D_SHADOW , dial.t_height );
  170.     y = height - ( 2 * dial.t_height ) - D_SHADOW - ( 2 * D_HEIGHT ) ;
  171.     if ( (type != D_WARNING) && (type != D_MESSAGE)) {
  172.         XMoveWindow ( dpy, dial.ok,
  173.             ( width/3 ) - ( dial.b_width/2 ), y );
  174.         XMoveWindow ( dpy, dial.cancel,
  175.             ( width*2 / 3 ) - ( dial.b_width/2 ), y );
  176.     }
  177.     else
  178.         XMoveWindow ( dpy, dial.ok,
  179.             ( width/2 ) - ( dial.b_width/2 ), y );
  180.     XMapSubwindows (dpy, dial.main );
  181.     XMapWindow ( dpy, dial.main );
  182.     XMapSubwindows ( dpy, dial.frame);
  183.     XMapRaised ( dpy, dial.frame);
  184.     XWindowEvent ( dpy, dial.main, ExposureMask, &event );
  185.     XWindowEvent ( dpy, dial.title, ExposureMask, &event );
  186.     XWindowEvent ( dpy, dial.ok, ExposureMask, &event );
  187.     if ( (type != D_WARNING) && (type != D_MESSAGE) ) 
  188.         XWindowEvent ( dpy, dial.cancel, ExposureMask, &event );
  189.     else 
  190.         XUnmapWindow ( dpy, dial.cancel );
  191.  
  192.     Display3D ( dpy, dial.title, dial.ts, dial.bs, 1, 0 );
  193.     Display3D ( dpy, dial.main, dial.ts, dial.bs, 1, 0 );
  194.     Display3D ( dpy, dial.ok, dial.ts, dial.bs, 1, 0 );
  195.     if ( (type != D_WARNING) && (type != D_MESSAGE) )
  196.         Display3D ( dpy, dial.cancel, dial.ts, dial.bs, 1, 0 );
  197.  
  198.     x = XTextWidth ( dial.font, DS_DIALOG, strlen (DS_DIALOG));
  199.     XDrawString ( dpy, dial.title, dial.gc, (width - x)/2,
  200.         dial.font -> ascent + 5, DS_DIALOG, strlen (DS_DIALOG) );
  201.     x = XTextWidth ( dial.font, DS_OK, strlen(DS_OK));
  202.     XDrawString ( dpy, dial.ok, dial.gc, (dial.b_width - x)/2,
  203.         dial.font -> ascent + 5, DS_OK, strlen(DS_OK));
  204.     x = XTextWidth ( dial.font, DS_CANCEL, strlen (DS_CANCEL));
  205.     if ( (type != D_WARNING) && (type != D_MESSAGE) )
  206.         XDrawString ( dpy, dial.cancel, dial.gc,
  207.         (dial.b_width - x)/2, dial.font -> ascent + 5,
  208.         DS_CANCEL, strlen (DS_CANCEL));
  209.  
  210.      str = GetStringFromWindow ( dial.main, dial.gc, dial.font,
  211.         s, 20, dial.font -> ascent + 20 , (char *) 0, 1 );
  212.  
  213.     XUnmapSubwindows ( dpy, dial.main );
  214.     XUnmapWindow ( dpy, dial.main );
  215.     XUnmapSubwindows ( dpy, dial.frame );
  216.     XUnmapWindow ( dpy, dial.frame );
  217.  
  218.     XReparentWindow ( dpy, dial.frame,
  219.         DefaultRootWindow ( dpy), 0, 0 );
  220.     return str;
  221. }
  222.  
  223.  
  224. /*
  225. **    Function name : GetStrinFromWindow
  226. **
  227. **    Description : Assure toute la gestion concernant
  228. **        l'entree d'une chaine de caracteres.
  229. **    Input : La fenetre, le contexte graphique, la fonte,
  230. **        le prompt, la position de depart, le type de
  231. **        reponse ( chaine complete, ou un seul caractere )
  232. **        et un flag pour savoir si on doit tenir compte 
  233. **        des 'ButtonPress'.
  234. **        
  235. **    Ouput : La chaine.
  236. */
  237. char *GetStringFromWindow ( w, gc, font, s, x, y, reply, flag )
  238.     Window        w;
  239.     GC        gc;
  240.     XFontStruct    *font;
  241.     register char     *s;
  242.     register int     x, y;
  243.     register char     *reply;
  244.     register int     flag;
  245. {
  246.     XEvent         event;
  247.     register int     length, cur_x, cur_x_old;
  248.     XComposeStatus     compose;
  249.     KeySym        keysym;
  250.     register int     start_x, max, font_h;
  251.     XWindowAttributes att;
  252.     register int type;
  253.         Window root, parent, **child;
  254.         unsigned int nchild;
  255.     
  256. #define MAXLENGTH     256
  257. #define VOLUME        10
  258.     static char string [MAXLENGTH];
  259.     static char buffer [MAXLENGTH];
  260.  
  261.     if ( strncmp ( s, "Warning", 7 ) == 0 )
  262.         type = D_WARNING;
  263.     else if ( strncmp ( s, "Message", 7 ) == 0 )
  264.         type = D_MESSAGE;
  265.     else
  266.         type = D_DIALOG;
  267.     XGetWindowAttributes ( dpy, w, &att );
  268.     XQueryTree ( dpy, w, &root, &parent, (Window **) &child, &nchild );
  269.  
  270.     if ( nchild == 0 ) 
  271.         XGrabPointer ( dpy, w, True, ButtonPress, GrabModeAsync,
  272.             GrabModeAsync, None, None, CurrentTime ); 
  273.     else 
  274.         /* On est dans le cas d'une dialog-box  avec bouttons*/
  275.         XGrabPointer ( dpy, w, True, ButtonPress, GrabModeAsync,
  276.             GrabModeAsync, w, None, CurrentTime );
  277.     if ( child != 0 )
  278.         XFree ( (char *) child );
  279.     XFlush (dpy );
  280.     max = att.width - 40;
  281.     font_h = font -> ascent + font -> descent;
  282.     if ( type == D_MESSAGE ) s += strlen ( "Message : " );
  283.     XDrawImageString ( dpy, w, gc, x, y, s, strlen (s) );
  284.     if ( type == D_DIALOG ) {
  285.         start_x = x + XTextWidth ( font, s, strlen (s) );
  286.         XFillRectangle ( dpy, w, gc, start_x, y - font -> ascent,  font_h/2, font_h );
  287.     }
  288.     cur_x = start_x;
  289.     string [0] = buffer [0] = buffer [1] = '\0';
  290.     for (;;) {
  291.         XNextEvent ( dpy, &event );
  292.         switch ( event.type ) {
  293.         case ButtonPress :
  294.             if ( flag == 0 ) continue;
  295.             if ( event.xbutton.window == dial.ok ) {
  296.                 Display3D ( dpy, dial.ok, dial.ts, dial.bs, 1, 1 );
  297.                 WaitButtonRelease ( event.xbutton.button );
  298.                 if ( strlen(string) )
  299.                     if ( string [0] != '~' )
  300.                         return string;
  301.                     else
  302.                         return ( (char *) ExpandTildeName ( string ));
  303.                 else
  304.                     return 0;
  305.             }
  306.             if ( event.xbutton.window == dial.cancel ) {
  307.                 Display3D ( dpy, dial.cancel, dial.ts, dial.bs, 1, 1 );
  308.                 WaitButtonRelease ( event.xbutton.button );
  309.                 string [0] = '\007';
  310.                 string [1] = '\0';
  311.                 return string;
  312.             }
  313.             break;
  314.         case KeyPress:
  315.             if ( (type == D_WARNING) || (type == D_MESSAGE) )
  316.                 continue;
  317.             XLookupString ( (XKeyEvent *) &event.xkey, buffer,MAXLENGTH, 
  318.                     &keysym, &compose );
  319.              /* Cas return, linefeed ou enter */
  320.             if ( (keysym == XK_Return) || (keysym == XK_KP_Enter)
  321.                 || (keysym == XK_Linefeed) ) {
  322.                 XClearArea( dpy, w, x,
  323.                        y - font -> ascent,
  324.                        XTextWidth ( font, string,
  325.                                strlen ( string )) +
  326.                        XTextWidth ( font, s, strlen (s)) + font_h/2, font_h, False );
  327.                 XUngrabPointer ( dpy, CurrentTime );
  328.                 if ( reply != 0 ) {
  329.                     (void) strncat ( string, "\n", 1 );
  330.                     return string;
  331.                 }
  332.                 if ( strlen ( string ))
  333.                     if ( string [0] != '~' )
  334.                         return string;
  335.                     else
  336.                         return ( (char *) ExpandTildeName ( string ));
  337.                 else 
  338.                     return 0;
  339.             }
  340.             /* Cas du Controle G */
  341.             else if ( (keysym == XK_Control_L) ||
  342.                   (keysym == XK_Control_R)) {
  343.                   continue;
  344.                   /* on ne fait rien */
  345.             }
  346.             else if ( keysym == XK_g  && event.xkey.state == ControlMask ) { 
  347.                 XUngrabPointer ( dpy, CurrentTime );
  348.                 string [0] = '\007';
  349.                 string [1] = '\0';
  350.                 return string;
  351.             }
  352.             /* Cas des caracteres imprimables */
  353.             else if ( ( (keysym >= XK_KP_Space)
  354.                     && (keysym <= XK_KP_9) )
  355.                   || ( (keysym >= XK_space)
  356.                          && (keysym <= XK_asciitilde) ) ) {
  357.                 if ( reply != 0 ) {
  358.                     XUngrabPointer ( dpy, CurrentTime );
  359.                            (void) strncat ( string, buffer, 1 );
  360.                            string [1] = '\0';
  361.                            return string;
  362.                 }
  363.                 if ( (strlen(string) + strlen(buffer))
  364.                     >= MAXLENGTH 
  365.                     || XTextWidth ( font, s, strlen (s))
  366.                         + XTextWidth ( font, string,
  367.                         strlen (string)) > max ) {
  368.                             XBell ( dpy, VOLUME );
  369.                             continue;
  370.                               }
  371.                 else {
  372.                     (void) strncat ( string, buffer, 1 );
  373.                       }
  374.             }
  375.             /* Cas shift */
  376.             else if ( (keysym >= XK_Shift_L )
  377.                   && (keysym <= XK_Shift_R) ) {
  378.                   /* On fait rien */
  379.                     continue;
  380.             }
  381.             /* Cas des fonctions speciales */
  382.             else if ( (keysym >= XK_F1) && (keysym <= XK_F35) ) {
  383.                 if ( buffer == NULL )
  384.                     (void) fprintf ( stderr, "Umapped function key\n" );
  385.                 /* on ne fait rien */
  386.                 else if ( (strlen(string) + strlen(buffer)) >= MAXLENGTH ) 
  387.                     XBell ( dpy, VOLUME );
  388.                 else {
  389.                     XBell ( dpy, VOLUME );
  390.                     continue;
  391.                 }
  392.             }
  393.  
  394.             /* Cas delete et backspace. */
  395.             else if ( (keysym == XK_BackSpace) || (keysym ==XK_Delete) ) {
  396.                 if ( (length = strlen(string)) > 0 ) {
  397.                     string [ length - 1 ] = 0;
  398.                     cur_x_old = cur_x;
  399.                     cur_x = start_x + 
  400.                         XTextWidth ( font, string, strlen (string));
  401.                     XClearArea( dpy, w, cur_x, y - font -> ascent,
  402.                            (font_h / 2) + (cur_x_old - cur_x),
  403.                            font_h, False );
  404.  
  405.                     XFillRectangle ( dpy, w, gc, cur_x, y - font -> ascent, 
  406.                         font_h/2, font_h );
  407.                 }
  408.                 else
  409.                     XBell ( dpy, VOLUME );
  410.                 continue;
  411.             }
  412.             else {
  413.                 XBell ( dpy, VOLUME );
  414.                 continue;
  415.             }
  416.  
  417.             XDrawImageString ( dpy, w, gc, cur_x, y, buffer, 1 );
  418.             cur_x_old = cur_x;
  419.             cur_x += XTextWidth ( font, buffer, 1 );
  420.             XFillRectangle ( dpy, w, gc, cur_x, y - font -> ascent,  font_h/2, font_h );
  421.             break;
  422.         }
  423.     }
  424. }
  425.  
  426.  
  427. /*
  428. **    Function name : ExpandTildeName
  429. **
  430. **    Description : Recherche le path de l'expression ~[name]
  431. **    Input : ~/, ~name 
  432. **    Ouput : Le path
  433. */
  434. char *ExpandTildeName ( name )
  435.     register char *name;
  436. {
  437.     register struct passwd *pwd;
  438.     register char *home;
  439.     register char *p = name + 1;
  440.     static char  buf [256];
  441.  
  442.     bzero ( buf, 128 );
  443.     if ( name [1] == '/' ) {    /* c'est moi */
  444.         if ( (home = (char *) getenv ( "HOME" )) == 0 )
  445.             return name;
  446.         (void) strcpy ( buf, home );
  447.         (void) strcat ( buf, name + 1 );
  448.     }
  449.     else { /* c'est un autre */
  450.         while ( *p && *p != '/' ) p++;
  451.         *p = 0;
  452.         pwd = getpwnam ( name + 1 );
  453.         if (  pwd ) {
  454.             (void) strcpy ( buf, pwd ->  pw_dir);
  455.             *p = '/';
  456.             (void) strcat ( buf, p );
  457.         }
  458.         else
  459.             return name;
  460.     }
  461.     return buf;
  462. }
  463.